library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ImageController is
  Port(	IMG_I2C_Clk : out std_logic;
			IMG_I2C_Data : out std_logic;
			IMG_Data : in std_logic_vector(9 downto 0);
			IMG_PIXEL_Clk : in std_logic;
			IMG_ROW_Clk : in std_logic;
			IMG_ROW_EN : in std_logic;
			IMG_VSYNC : in std_logic;
			IMG_RST : out std_logic;
			
			OEM_I2C_Clk : out std_logic;
			OEM_I2C_Data : out std_logic;
			OEM_Data : out std_logic_vector(9 downto 0);
			OEM_PIXEL_Clk : out std_logic;
			OEM_ROW_Clk : out std_logic;
			OEM_ROW_EN : out std_logic;
			OEM_VSYNC : out std_logic;
			
			Clk_100MHz : in std_logic;
			
			SW : in std_logic_vector(3 downto 0);
			LED : out std_logic_vector(3 downto 0));
end ImageController;

architecture beh of ImageController is

  component EdgeDetector is
    port (Sig : in std_logic;
          Clk : in std_logic;
          FallingEdge : out std_logic;
          RisingEdge : out std_logic);
  end component;

  signal pclk,fpga_clk,row_en : std_logic:='0';
  signal dat : std_logic_vector(15 downto 0);
  
  signal vsync,hsync : std_logic;
  signal endofrow,endofframe : std_logic;
  signal endofframe1 : std_logic_vector(1 downto 0):="00";
  
  signal rowCount : std_logic_vector(8 downto 0):=(others=>'0');
  signal colCount : std_logic_vector(9 downto 0):=(others=>'0');
  
  signal count,cnt : std_logic_vector(15 downto 0):=X"0000";
  
  signal hsize : natural:=752;
  signal vsize : natural:=480;
  
  type states is (calibrate,frameStart);
  signal cs : states:=calibrate;

  signal row_rise,row_fall : std_logic;

begin

	IMG_I2C_Clk <='0';
	IMG_I2C_Data <='0';
	IMG_RST <='1';
			
	OEM_I2C_Clk <='0';
	OEM_I2C_Data <='0';
	OEM_Data <=(others=>'0');
	OEM_PIXEL_Clk <='0';
	OEM_ROW_Clk <='0';
	OEM_ROW_EN <='0';
	OEM_VSYNC <=vsync;
			
	LED <=(others=>'0');
  
  fpga_clk<=Clk_100MHz;
  pclk<=IMG_PIXEL_Clk;
  row_en<=IMG_ROW_EN;
  
  RowEdge: EdgeDetector port map(fpga_clk,row_en,row_rise,row_fall);
  
  process(pclk)
  begin
	if rising_edge(pclk) then
		case cs is
			when calibrate =>
				if row_en = '0' then
					count<=count+1;
				else 
					if count > 1000 then
						cs<=frameStart;
					end if;
					count<=(others=>'0');
				end if;
			when frameStart =>
				if row_rise = '1' then
					rowCount<=rowCount + 1;
					vsync<='1';
				end if;
				
				if row_en = '1' then
					colCount <= colCount + 1;
				end if;
				
				if (rowCount = vsize) and (colCount = hsize) then
					rowCount<=(others=>'0');
					colCount<=(others=>'0');
					
					vsync <= '0';
				end if;
		end case;
	end if;
  end process;
  
end beh;